package CCNQ::Billing::Bill;
# Copyright (C) 2006, 2007  Stephane Alnet
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 

#
# For more information visit http://carrierclass.net/
#
use strict; use warnings;

=pod

    Abstract class. Adds default locations for the output files.

=cut

use base qw(CCNQ::Billing::CallRecords);
use CCNQ::Billing::Info;

sub _init($$)
{
    my $self = shift;
    $self->{period} = shift;
    $self->{output_dir} = shift;

    $self->{billing_info} = new CCNQ::Billing::Info;
    $self->{cdr} = $self->open_cdr;

    $self->SUPER::_init(@_);
}

use IO::File;

sub _open
{
    my $self = shift;
    my ($file) = @_;
    my $out = new IO::File "| bzip2 > $self->{output_dir}/${file}.bz2" or die "open($self->{output_dir}/${file}.bz2): $!";
    return $out;
}

=pod

    open_err
    
        Open the error file where we store rejects, etc.

=cut

sub open_err
{
    my $self = shift;
    return $self->_open("$self->{period}-errors.html");
}

=pod

    open_cdr
    
        Open the CDR file (where we store our finalized CDRs).

=cut

sub open_cdr
{
    my $self = shift;
    return $self->_open("$self->{period}-cdr.txt");
}

=pod
    register_record
        Given a record, if the record is complete, outputs it as a CDR,
        otherwise registers it for later completion.
=cut

sub register_record($)
{
    my $self = shift;
    my $record = shift;
    my $callref = $record->{callref};

    if( exists $record->{start} and exists $record->{stop} )
    {
        my $secs_start = $record->{start};
        my $secs_end   = $record->{stop};
        my $duration = $secs_end-$secs_start;

        $record->{duration} = $duration;

        $record->{billable_duration} = 
            $record->{billable_call} ? $duration : 0;

        my @time = localtime($record->{start});
        $record->{date} = sprintf('%04d%02d%02d',$time[5]+1900,$time[4]+1,$time[3]);
        $record->{time} = sprintf('%02d:%02d:%02d',$time[2],$time[1],$time[0]);

        if(defined $record->{billable} and $record->{billable} ne '')
        {
            # Print out the CDR.
            my $cdr = $self->format_record($record);
            $self->{cdr}->print( $cdr ) if defined $cdr;
            # Mark the record as completed so that we do not go back to it.
            $self->mark_record_completed($callref);
            return 1;
        }
        else
        # We don't know who to bill for this call.
        {
            $self->warn ("<br>No account for: "
                .join( ';', map { qq($_=').(defined $record->{$_} ? $record->{$_} : '').q(') } sort keys %{$record} )
                .": $_\n");
            # Mark the record as completed so that we do not go back to it.
            $self->mark_record_completed($callref);
            return 0;
        }
    }

    $self->register_incomplete_record($callref,$record);
    return 1;
}

1;
